﻿using System;
using System.IO;
using System.Text.Json;
using CommunityToolkit.Mvvm.DependencyInjection;
using MinecraftEnchantCalculator.Abstractions;
using MinecraftEnchantCalculator.Data.Entity;
using MinecraftEnchantCalculator.Data.Table;
using MinecraftEnchantCalculator.Enums;

namespace MinecraftEnchantCalculator.Data;

/// <summary>
///   数据访问层核心类，负责加载和提供应用程序所需的所有游戏数据
///   包括附魔冲突规则、物品可用附魔、附魔属性及物品信息等
/// </summary>
public class Db
{
  /// <summary>
  ///   静态构造函数，初始化时加载所有JSON数据文件
  ///   数据文件位于应用程序目录下的"Assets/ItemJson"文件夹中
  /// </summary>
  static Db()
  {
    var jsonDir = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Assets", "ItemJson");

    try {
      Conflicts = LoadTable<Conflict>(Path.Combine(jsonDir, "Conflicts.json"));
      Applicables = LoadTable<Applicable>(Path.Combine(jsonDir, "Applicables.json"));
      Enchantments = LoadTable<Enchantment>(Path.Combine(jsonDir, "Enchantments.json"));
      Items = LoadTable<Item>(Path.Combine(jsonDir, "Items.json"));
    }
    catch (Exception /* ex */) {
      // TODO: Handle error
    }
  }

  /// <summary>
  ///   附魔冲突规则表，存储各附魔之间的互斥关系数据
  ///   对应JSON文件：Conflicts.json
  /// </summary>
  public static TableStruct<Conflict> Conflicts { get; } = null!;

  /// <summary>
  ///   物品可用附魔表，存储各物品可应用的附魔列表数据
  ///   对应JSON文件：Applicables.json
  /// </summary>
  public static TableStruct<Applicable> Applicables { get; } = null!;

  /// <summary>
  ///   附魔属性表，存储所有附魔的基础属性（如最大等级、乘数等）数据
  ///   对应JSON文件：Enchantments.json
  /// </summary>
  public static TableStruct<Enchantment> Enchantments { get; } = null!;

  /// <summary>
  ///   物品信息表，存储所有可附魔物品的基础信息（如名称、图标等）数据
  ///   对应JSON文件：Items.json
  /// </summary>
  public static TableStruct<Item> Items { get; } = null!;

  /// <summary>
  ///   从指定JSON文件加载数据并反序列化为指定类型的表结构
  /// </summary>
  /// <typeparam name="T">表行数据的实体类型</typeparam>
  /// <param name="filePath">JSON数据文件的完整路径</param>
  /// <returns>包含表结构和数据的TableStruct实例</returns>
  /// <exception cref="Exception">当文件加载或反序列化失败时抛出</exception>
  private static TableStruct<T> LoadTable<T>(string filePath)
  {
    var jsonContent = File.ReadAllText(filePath);
    return JsonSerializer.Deserialize<TableStruct<T>>(jsonContent)
           ?? throw new Exception($"Failed to load {filePath}");
  }
}